goto
、標記:goto 格式: goto [標記];
標記 格式: [標記]:
用於無條件跳躍到標記語句,基礎用法:
printf("Hello");
goto label;
printf(" World!!!");
label:
輸出: Hello
跳過了 printf(" World!!!");
語句。
goto
陳述式 不能夠在函數間跳躍,[標記]
這個識別項擁有自己的命名空間,[標記]
或者 goto
目標。[標記]
的視野範圍(scope)不會受 for
, while
等區域局限,goto
可以多個,[標記]
是唯一的。goto
一直以來充滿爭議,被不建議使用,
一些程式風格禁止使用 goto
陳述式。
主要原因是 goto
陳述式 容易大幅降低可讀性,
甚至成為不可維護的「麵條程式碼」,
使程式事情的難以追蹤和理解,以及修改。
有一些為 goto
陳述式辯護的人認為,
加以限制地使用GOTO陳述式不會導致低質素的程式碼,
並且聲稱一些任務如果不使用一條或多條GOTO陳述式是無法被直接實現的。
如有限狀態自動機的實現、跳出巢狀迴圈以及例外處理。
goto
的實現方式:先嘗試一個用 goto
+ 標記 做例外處理的例子:
/*陳述式*/
if(/*錯誤檢測*/){
goto ex_catch;
}
back_to_call:
/*陳述式*/
ex_catch:
/*錯誤處理*/
goto back_to_call;
可讀性已經很差,不過下面那個更加離譜......。
當錯誤檢測成立,跳轉到錯誤處理,
最後返回錯誤檢測後的位置。
上式與 try-catch
(例外處理) 的跳轉類似,
會返回發生錯誤後的位置。
goto
的實現方式,實現方式會變成如何?
int error_is_not_happened = 1;
do{
do{
if(error_is_not_happened){
/*陳述式*/
if(/*錯誤檢測*/){
error_is_not_happened = 0
break;
}
}
error_is_not_happened = 1
/*陳述式*/
while(0);
/*錯誤處理*/
while(!error_is_not_happened);
可能有更簡單的實現方法,不過我隨便/暫時想到的是這樣。
宣告了變數標記 error_is_not_happened
,非零為真。
利用 do{}while(0)
加上錯誤檢測成立後的 break;
,
快速跳離整個陳述式,到達函式的最底部分,進行錯誤處理。
再利用 while(!error_is_not_happened)
判斷,
判斷到達這裏(最底部分)的原因是否因為發生了錯誤,
若是,返回最頂部分。
若否,即是以正常運行步驟到達最底部分,允許離開。
返回最頂部分後,利用 if(error_is_not_happened){}
,
快速返回錯誤檢測後的位置,
再把 error_is_not_happened
標記賦值為一(true),允許從最底部分離開。
【其實我是覺得上面這一大堆文字已經沒有什麼人想讀了。】
這樣的可讀性絕對不高吧......這還是只有一個例外處理的情況。
更多例外處理需要使用 更多的 變數標記,
更多的 do{}while()
, break
,以及更多的標記判斷。
所以在某些情況下使用 goto
的確會比較方便,
甚至比較可讀。
goto - 維基百科,自由的百科全書
https://zh.wikipedia.org/zh-hk/Goto#%E5%AF%B9%E4%BA%8Egoto%E4%BD%BF%E7%94%A8%E7%9A%84%E6%89%B9%E8%AF%84
麵條式程式碼 - 維基百科,自由的百科全書
https://zh.wikipedia.org/wiki/%E9%9D%A2%E6%9D%A1%E5%BC%8F%E4%BB%A3%E7%A0%81